# coding: utf8
# try something like
#from makan import *

def call():
    session.forget()
    return service()


@service.xmlrpc    
def test():
    return 'it is working'

def index(): 
    return dict(message= 'welcome')

def add():
    if request.get_vars:   
        vars = request.get_vars
        # TODO: don't insert if email was found in DB
        db.users.insert(firstname = vars.firstname,
                        lastname = vars.lastname,
                        email = vars.email,
                        birthday = vars.birthday,
                        password = vars.password,
                        gender = vars.gender)
        return T("done")
    else:
        return dict()

def update():
    if request.get_vars:
        # TODO: don't update if email was found in DB
        db(db.users.id == request.args[0]).update(
            firstname = request.get_vars.firstname,
            lastname = request.get_vars.lastname,
            email = request.get_vars.email,
            password = request.get_vars.password,
            birthday = request.get_vars.birthday,
            gender = request.get_vars.gender,
        )
        return T("done")
   
    else:
        user = db.users[request.args[0]]
        if not user: return "user not found!"
        return dict(user = user)

def read():
    user = db(db.users.email == request.args[0]).select()
    if not user: return "user not found"
    return dict(user = user)

def delete():
    db(db.users.email == request.args[0]).delete()
    return T("done")

def list():
    users = db().select(db.users.ALL)
    return dict(users = users)

def search():
    return dict()
    
def authen():
#    FORM('Your name:',
#              INPUT(_name='email', requires=IS_NOT_EMPTY()),
#              'Password:',
#              INPUT(_name='password', _type='password'),
#              INPUT(_type='submit'),
#              INPUT(_name='_formname',_type='hidden', _value='login'),
#              INPUT(_name='_next', _type='hidden', _value='/makan/users/index'))
#    auth.environment.request.args[0]='register'
#    form=auth() 
    return dict(form1=auth.login(), form2=auth.register())
    

def delete_user_folllower():
    result = -1
    data = {}
    if request.get_vars: 
        vars = request.get_vars

        #get last checkin
        q1 = db.user_followers.follower ==  vars.user_id
        q2 = db.user_followers.user ==  vars.followed_id
        rows =  db(  q1 & q2 ).select().first()
      
        if rows: 
            data["me"] = rows.follower.first_name + " " + rows.follower.last_name
            data["follower"] = rows.user.first_name + " " + rows.user.last_name
            result =  db(  db.user_followers.id == rows.id ).delete()

    return dict(result  = result , data = data )


def delete_place_folllower():
    result = -1
    data = {}
    if request.get_vars: 
        vars = request.get_vars

        #get last checkin
        q1 = db.place_followers.follower ==  vars.user_id
        q2 = db.place_followers.place ==  vars.followed_id

        rows  =  db(  q1 & q2 ).select().first()
        if rows :
             data["me"] = rows.follower.first_name + " " + rows.follower.last_name
             data["place"] = rows.place.name 
             result =  db( db.place_followers.id == rows.id ).delete()
    return dict(result  = result , data = data )
#######################################

def queryXInArea(lat, long, delta, username='', placename=''):
    ''' searches given area for all/filtered people/places''' 
    checkinsList = usersList = []
    checkin = ''
#    delta = 0.1
    if lat:    
        Llat = lat - delta; Rlat = lat + delta
        Dlong = long - delta; Ulong = long + delta
        
        #the query that get all places in the given area 
        query1 = (db.places.lat <= Rlat) & (db.places.lat >= Llat)
        
        query2 = (db.places.long <= Ulong) & (db.places.long >= Dlong)
        
        # to filter places
        if placename:
          query1 = query1 & (db.places.name == placename)
  
        placesList = db(query1)(query2).select()

        #get all people in the given area
        for place in placesList:
            if place.checkins:
                for checkinId in place.checkins:
                    checkin = db.checkins[checkinId]
                    user = db.users[checkin.user]
                    if username:
                        if user.first_name == username or user.last_name == username:
                            usersList.append(user)
                    else:
                        usersList.append(user)

    else: 
        usersList = placesList = False
    
    return dict(usersList=usersList, placesList=placesList)

#######################################
#working locally
@service.xmlrpc
def xSuggestFriends(lat, long, delta = 0.01):
    result = {}
    suggestedFriends = coreSuggestFriends(lat, long, delta)
    if suggestedFriends:
        for user in suggestedFriends:
            result[str(user.id)] = user.as_dict()
    else:
        result = 'no users found'
    return str(result)

def suggestFriends():
    if request.get_vars:
        lat = float(request.get_vars.lat)
        long = float(request.get_vars.long)
        if request.get_vars.delta:
            delta = float(request.get_vars.delta)
        else:
            delta = 0.01
        suggestedFriends = coreSuggestFriends(lat, long, delta)
        if not suggestedFriends:
            suggestedFriends = 'no friends found'
    else:
        suggestedFriends = 'no coordinates found'
    
    return dict(suggestedFriends = suggestedFriends)


def coreSuggestFriends(lat, long, delta):
    ''' it searches people around a single point'''
#    delta = 0.01
    if lat:
        usersList = queryXInArea(lat, long, delta)['usersList']
        suggestedFriends = usersList[0:3]
        
    else:
        suggestedFriends = False
        
    return suggestedFriends

########################################
# working locally
@service.xmlrpc
def xGetProfile(uid):
    result = {}
#	uid = int(uid)
    if uid:
		user = coreGetProfile(uid)
#        typee = type(user)
#		return str(type(user))
		if user:
			result[str(user.id)] = user.as_dict()
		else:
			result = 'no such id'
    else:
        result = 'enter user id'
    return str(result)


def getProfile():
    if request.get_vars.uid:
        uid = int(request.get_vars.uid)
        user = coreGetProfile(uid)
        if not user:
            user = 'no such id'
    else: 
        user= 'please enter id'
    return dict(user = user)
    
    
def coreGetProfile(uid):
    if uid:
        user = db.users[uid]
    else:
        user = False 
    return user

###########################################
#working locally
@service.xmlrpc
def xShowNearby(uid, lat, long, delta = 0.01):
    result1 = result2 = nearby = {}
    if lat:
        friendsAround, placesAround = coreShowNearby(uid, lat, long, delta)
        if friendsAround:
            for user in friendsAround:
                result1[str(user.id)] = user.as_dict()
#                return result1
            nearby['friends'] = result1
        else:
            result1 = 'no friends found'
#        return result1
        if placesAround:
            for place in placesAround:
                result2[str(place.id)] = place.as_dict()
            nearby['places'] = result2
        else:
            result2 = 'no friends found'
    else:
        nearby = 'enter coordinates'
    
    return str(nearby)

@auth.requires_login()
def showNearby():
    if request.get_vars:
        lat = float(request.get_vars.lat)
        long = float(request.get_vars.long)
        if request.get_vars.delta:
            delta = float(request.get_vars.delta)
        else:
            delta = 0.01
        
        uid = auth.user.id
        friends, places = coreShowNearby(uid, lat, long, delta)
        
        if not friends: friends = 'no friends found'
        if not places: places = 'no places found'    
    else:
        friends = places = 'enter coordinates'
    return dict(friends=friends, places=places)


def coreShowNearby(uid, lat, long, delta):
    ''' searches friends and places nearby'''
    friendsAround = placesAround = []
    if lat:
        peoplePlaces = queryXInArea(lat, long, delta)
        
        people = peoplePlaces['usersList']
        placesAround = peoplePlaces['placesList']
        
        following = db.users[uid].following
        #TODO: use the contains operator
        for user in people:
            if user.id in following:
                friendsAround.append(user)
    else:
        friendsAround = placesAround = False
    
    return (friendsAround, placesAround)

################################################
#working locally
@service.xmlrpc
def xSearchPeople(name, lat, long, delta = 0.01):
    result = {}
    if lat:
        usersList = coreSearchPeople(lat, long, delta, name)
        if usersList:
            for user in usersList:
                result[str(user.id)] = user.as_dict()
        else:
            result = 'no people found'
    else:
        result = 'enter coordinates'
    return str(result)


def searchPeople():
    name = request.get_vars.name
    if request.get_vars:
        lat = float(request.get_vars.lat)
        long = float(request.get_vars.long)
        if request.get_vars.delta:
            delta = float(request.get_vars.delta)
        else:
            delta = 0.01
        usersList = coreSearchPeople(lat, long, delta, name)
        if not usersList:
            usersList = 'no people found'
    else:
        usersList = 'enter coordinates'
    return dict(usersList = usersList)
        

def coreSearchPeople(lat, long, delta, name):
    if lat:
        usersList = queryXInArea(lat, long, delta, username= name)['usersList']
    else:
        usersList = False
    return usersList

############################################

def coreFollow(uid, fid):
    """
    uid wants to follow fid
    check uid, fid
    add fid to uid following
    add uid to fid followers
    """

    u = db.users[uid]
    f = db.users[fid]
    
    if not u: return T("Bad user id")
    if not f: return T("Bad Following id")

    if int(uid) == int(fid):
        return T("you can't follow yourself")
    
    uid_following = u.following
    if int(fid) in uid_following:
        return T("already following")
    else:
        uid_following.append(fid)
        u.update_record(following = uid_following)

        fid_followers = f.followers
        fid_followers.append(uid)
        f.update_record(followers = fid_followers)
        return T("done")

@service.xmlrpc
def xFollow(uid, fid):
    msg = coreFollow(uid, fid)
    return jsonString(msg)

@auth.requires_login()
def follow():
    uid = auth.user.id
    fid = request.args[0]
    return coreFollow(uid, fid)

############################################################################

def coreUnFollow(uid, fid):
    """
    uid wants to unfollow fid
    check uid, fid
    remove fid to uid following
    remove uid to fid followers
    """
    
    fid = int(fid)
    uid = int(uid)
    
    u = db.users[uid]
    f = db.users[fid]
    
    if not u: return T("Bad user id")
    if not f: return T("Bad Following id")

    if int(uid) == int(fid):
        return T("you can't unfollow yourself")
    
    uid_following = u.following
    
    if fid in uid_following:
        uid_following.remove(fid)
        u.update_record(following = uid_following)
        
        fid_followers = f.followers
#        return uid
        fid_followers.remove(uid)
        f.update_record(followers = fid_followers)
        return T("done")
    else:
        return T("you are not following")

@service.xmlrpc
def xUnfollow(uid, fid):
    msg = coreUnFollow(uid, fid)
    return jsonString(msg)

@auth.requires_login()
def unfollow():
    uid = auth.user.id
    fid = request.args[0]
    return coreFollow(uid, fid)

############################################################################

def coreGetFollowers(uid):

    user = db.users[int(uid)]
    
    if not user: return T("bad user id")

    result = {}
    for f in user.followers:
        follower = db.users[f]
        result[str(f)] = { "fistname": follower.first_name, "lastname": follower.last_name }

    return result

@auth.requires_login()
def getFollowers():
    myDict = coreGetFollowers(request.args[0])
    return dict(d = myDict)

@service.xmlrpc
def xGetFollowers(uid):
    return coreGetFollowers(uid)

#############################################################################

def coreGetFollowing(uid):

    user = db.users[int(uid)]
    
    if not user: return T("bad user id")

    result = {}
    for f in user.following:
        u = db.users[f]
        result[str(f)] = { "firstname": u.first_name, "lastname": u.last_name }

    return result

@auth.requires_login()
def getFollowing():
    myDict = coreGetFollowing(request.args[0])
    return str(myDict)

@service.xmlrpc
def xGetFollowing(uid):
    msg = coreGetFollowing(uid)
    return str(msg)
##############################################################################






    
    
    
    